package com.example.demo.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.example.demo.mapper.SysDictItemMapper;
import com.example.demo.mapper.SysDictMapper;
import com.example.demo.model.converter.SysDictConverter;
import com.example.demo.model.converter.SysDictItemConverter;
import com.example.demo.model.core.PageVo;
import com.example.demo.model.entity.SysDict;
import com.example.demo.model.entity.SysDictItem;
import com.example.demo.model.form.DictForm;
import com.example.demo.model.form.DictItemForm;
import com.example.demo.model.form.DictItemSaveForm;
import com.example.demo.model.query.DictItemQuery;
import com.example.demo.model.query.DictQuery;
import com.example.demo.model.vo.DictItemVO;
import com.example.demo.model.vo.DictVO;
import com.example.demo.model.vo.OptionVO;
import com.example.demo.service.SysDictService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


@Service
public class SysDictServiceImpl implements SysDictService {

    @Autowired
    private SysDictMapper sysDictMapper;
    @Autowired
    private SysDictItemMapper sysDictItemMapper;
    @Autowired
    private SysDictConverter sysDictConverter;
    @Autowired
    private SysDictItemConverter sysDictItemConverter;

    @Override
    public void add(DictForm form) {
        QueryWrapper wrapper = QueryWrapper.create().eq("name", form.getName());
        long count = sysDictMapper.selectCountByQuery(wrapper);
        Assert.isTrue(count == 0, "字典名称已存在");
        wrapper = QueryWrapper.create().eq("dict_code", form.getDictCode());
        count = sysDictMapper.selectCountByQuery(wrapper);
        Assert.isTrue(count == 0, "字典编码已存在");
        SysDict entity = sysDictConverter.toEntity(form);
        sysDictMapper.insert(entity);
    }

    @Override
    public void update(DictForm form) {
        QueryWrapper wrapper = QueryWrapper.create().eq("name", form.getName()).ne("id", form.getId());
        long count = sysDictMapper.selectCountByQuery(wrapper);
        Assert.isTrue(count == 0, "字典名称已存在");
        wrapper = QueryWrapper.create().eq("dict_code", form.getDictCode()).ne("id", form.getId());
        count = sysDictMapper.selectCountByQuery(wrapper);
        Assert.isTrue(count == 0, "字典编码已存在");
        SysDict entity = sysDictConverter.toEntity(form);
        sysDictMapper.update(entity);
    }

    @Override
    @Transactional
    public void delete(List<Long> ids) {
        List<SysDict> sysDicts = sysDictMapper.selectListByIds(ids);
        Set<String> dictCodeList = sysDicts.stream().map(SysDict::getDictCode).collect(Collectors.toSet());
        sysDictItemMapper.deleteByQuery(QueryWrapper.create().in("dict_code", dictCodeList));
        sysDictMapper.deleteBatchByIds(ids);
    }

    @Override
    public PageVo<DictVO> page(DictQuery query) {
        QueryWrapper wrapper = new QueryWrapper();
        if (StrUtil.isNotBlank(query.getName())) {
            wrapper.like(SysDict::getName, query.getName());
        }

        Page<SysDict> page = sysDictMapper.paginate(query.getPageNum(), query.getPageSize(), wrapper);
        PageVo<SysDict> pageVo = new PageVo<>();
        pageVo.setList(page.getRecords());
        pageVo.setTotal(page.getTotalRow());
        return sysDictConverter.toPageVo(pageVo);
    }

    @Override
    public DictForm form(Long id) {
        SysDict sysDict = sysDictMapper.selectOneById(id);
        Assert.notNull(sysDict,"字典不存在");
        return sysDictConverter.toForm(sysDict);
    }

    @Override
    public void addItem(DictItemForm form) {
        QueryWrapper wrapper = QueryWrapper.create().eq("value", form.getValue()).eq("dict_code", form.getDictCode());
        long count = sysDictItemMapper.selectCountByQuery(wrapper);
        Assert.isTrue(count == 0, "字典项值已存在");
        wrapper = QueryWrapper.create().eq("label", form.getLabel()).eq("dict_code", form.getDictCode());
        count = sysDictItemMapper.selectCountByQuery(wrapper);
        Assert.isTrue(count == 0, "字典项标签已存在");
        SysDictItem entity = sysDictItemConverter.toEntity(form);
        sysDictItemMapper.insert(entity);
    }

    @Override
    public void updateItem(DictItemForm form) {
        QueryWrapper wrapper = QueryWrapper.create().eq("value", form.getValue()).eq("dict_code", form.getDictCode()).ne("id", form.getId());
        long count = sysDictItemMapper.selectCountByQuery(wrapper);
        Assert.isTrue(count == 0, "字典项值已存在");
        wrapper = QueryWrapper.create().eq("label", form.getLabel()).eq("dict_code", form.getDictCode()).ne("id", form.getId());
        count = sysDictItemMapper.selectCountByQuery(wrapper);
        Assert.isTrue(count == 0, "字典项标签已存在");
        SysDictItem entity = sysDictItemConverter.toEntity(form);
        sysDictItemMapper.update(entity);
    }

    @Override
    public void deleteItem(List<Long> ids) {
        sysDictItemMapper.deleteBatchByIds(ids);
    }

    @Override
    public PageVo<DictItemVO> pageItem(DictItemQuery query) {
        QueryWrapper wrapper = QueryWrapper.create().eq("dict_code", query.getDictCode());
        if (StrUtil.isNotBlank(query.getKeyword())) {
            wrapper.and(queryWrapper -> {
                queryWrapper.like("label", query.getKeyword()).or(w -> {
                    w.like("value", query.getKeyword());
                });
            });
        }
        Page<SysDictItem> page = sysDictItemMapper.paginate(query.getPageNum(), query.getPageSize(), wrapper);
        PageVo<SysDictItem> pageVo = new PageVo<>();
        pageVo.setList(page.getRecords());
        pageVo.setTotal(page.getTotalRow());
        return sysDictItemConverter.toPageVo(pageVo);
    }

    @Override
    public DictItemForm formItem(Long id) {
        SysDictItem sysDictItem = sysDictItemMapper.selectOneById(id);
        Assert.notNull(sysDictItem,"字典项不存在");
        return sysDictItemConverter.toForm(sysDictItem);
    }

    @Override
    public void itemsSave(DictItemSaveForm form) {
        String dictCode = form.getDictCode();
        List<DictItemForm> dictItemFormList = form.getItems();
        Set<String> itemValueSet = dictItemFormList.stream().map(DictItemForm::getValue).collect(Collectors.toSet());
        // 删除掉没有的项
        sysDictItemMapper.deleteByQuery(QueryWrapper.create().eq("dict_code", dictCode).notIn("value", itemValueSet));
        // 插入或更新
        for (DictItemForm dictItemForm : dictItemFormList) {
            // 判断是否重复

            QueryWrapper wrapper = QueryWrapper.create().eq("value", dictItemForm.getValue()).eq("dict_code", dictCode);
            SysDictItem sysDictItem = sysDictItemMapper.selectOneByQuery(wrapper);
            if (sysDictItem == null) {
                SysDictItem entity = sysDictItemConverter.toEntity(dictItemForm);
                sysDictItemMapper.insert(entity);
            }
            else {
                SysDictItem entity = sysDictItemConverter.toEntity(dictItemForm);
                sysDictItemMapper.update(entity);
            }
        }
    }

    @Override
    public List<OptionVO<String>> itemsOption(String dictCode) {
        List<SysDictItem> dictItemList = sysDictItemMapper.selectListByQuery(QueryWrapper.create().eq("dict_code", dictCode));
        return dictItemList.stream().map(item -> new OptionVO<>(item.getValue(), item.getLabel(), item.getTagType())).toList();
    }


    @Override
    public List<DictItemVO> listDictItem(String dictCode) {
        List<SysDictItem> sysDictItems = sysDictItemMapper.selectListByQuery(QueryWrapper.create().eq("dict_code", dictCode));
        return sysDictItemConverter.toVoList(sysDictItems);
    }

    @Override
    public DictItemVO getDictItem(String dictCode, String itemCode) {
        SysDictItem sysDictItem = sysDictItemMapper.selectOneByQuery(QueryWrapper.create().eq("dict_code", dictCode).eq("value", itemCode));
        return sysDictItemConverter.toVo(sysDictItem);
    }
}




